#include "protocole.h"




/**
 * \function verifIp("char* ip")
 * \brief : Verification que la chaine de caractere ip correspond a une adresse ip valide
 * \param : ip chaine de caracteres
 * \return un booleen indiquant si l'adresse ip est valide
 **/
int verifIpV4(char* ip){
  int i,j=0,k;
  char bloc[4];//Chaine de caracteres representant un bloc entre 2 points dans l'adresse ip
  long int nb;//Valeur du bloc courant
  for(i=0;i<4;i++){
    k=0;
    while((ip[j]!='\0')&&(ip[j]!='.')&&(k<3)){//On remplit la variable bloc
      bloc[k]=ip[j];
      j++;
      k++;
    }
    bloc[k]='\0';
    if((i<3)&&(ip[j]=='\0')){//Fin de la chaine avant d'avoir eu suffisamment de caracteres
       return 0;
    }
    else if((i==3)&&(ip[j]!='\0')){//Il y a des caracteres apres le 4eme nombre
       return 0;
    }
    else if(k==0){
       return 0;
    }
    else{
      char* err="\0";
      nb=strtol(bloc,&err,10);
      if(strcmp(err,"\0")!=0){
	return 0;
      }
      else if(nb>255){
	return 0;
      }
      else{
	j++;
      }
    }
  }
  return 1;
}

int verifBlocIpV6(char* bloc){
  if(strlen(bloc)>4){
    return 0;
  }
  char* err="\0";
  long int i = strtol(bloc,&err,16);
  if(strcmp(err,"\0")!=0){
    return 0;//Le bloc n'est pas au format hexadecimal
  }
  return 1;
}

int verifIpV6(char* ip){
  int i,j=0,k;//Variables de boucle
  int paire=0;//Nombre de '::'
  char bloc[16];//Chaine de caracteres representant un bloc entre 2 ":" dans l'adresse ip
  for(i=0;i<8;i++){
    k=0;
    while((ip[j]!='\0')&&(ip[j]!=':')&&(ip[j]!='.')){//On remplit la variable bloc
      bloc[k]=ip[j];
      j++;
      k++;
    }
    if(ip[j]=='.'){//Si les deux derniers blocs sont en notation decimale pointee(W.X.Y.Z)
      while(ip[j]!='\0'){
	bloc[k]=ip[j];
	j++;
	k++;
      }
      bloc[k]='\0';
      return verifIpV4(bloc);
    }

    bloc[k]='\0';
    if((i<7)&&(ip[j]=='\0')&&(paire==0)){//Fin de la chaine avant d'avoir eu suffisamment de caracteres
      return 0;
    }
    else if((i==7)&&(ip[j]!='\0')&&(paire==0)){//Il y a des caracteres apres le 8eme bloc
      return 0;
    }
    else if((ip[j]=='\0')&&(paire==1)){//Si il y a un '::', l'adresse est valide avec moins de 8 blocs
      return 1;
    }
    else if(!verifBlocIpV6(bloc)){//On verifie que les blocs sont de bonne taille et au format hexadecimal
      return 0;
    }
    else{
      if((strlen(bloc)==0)&&(i!=0)){//Si on a la sequance '::'
	paire++;
      }
      if(paire>1){//si on a deux fois '::', l'adresse ip n'est pas valide
	return 0;
      }
      j++;
    }
  }
  return 1;
}

int verifIp(char* ip){
  return (verifIpV4(ip)||verifIpV6(ip));
}

int checkdirexist(const char * path){
	if (opendir(path) == NULL) {
		return -1;
	}
	else
		return 0;
}


int cmd_set(char *args,char ** IP_S,int * PORT_S, char ** PATH_S){
	if(args == NULL){//Liste des options disponibles dans le programme
		printf("Options disponibles :\n\n");
		printf("ip : %s\n",*IP_S);
		printf("port : %d\n",*PORT_S);
		printf("path : %s\n",*PATH_S);
		printf("\n");
		return 0;
	}
	
	else{//Modifie la valeur d'une option
		int i=0,j=0;
		char* option=malloc(MAX_TAILLE_OPTION*sizeof(char));//Dans un premier temps on recupere le nom de l'option
		char* valeur=malloc(MAX_TAILLE_VALEUR*sizeof(char));//et sa valeur
		while((args[i]!= '=') && (!isblank(args[i]))){//Tous les caracteres avant un espace ou le symbole espace sont dans option
			if(args[i]=='\0'){
				printf("Erreur de syntaxe, pour modifier la valeur d'une option, la bonne syntaxe est les suivante : option=valeur\n\n");
				option=NULL;
				valeur=NULL;
				break;
			}
			option[i]=args[i];
			i++;
		}
		
		if(option!=NULL){
			
			option[i]='\0';
			while(((args[i]== '=') || (isblank(args[i])))&&(args[i]!='\0')){//On va jusqu'au debut du deuxieme mot	 
				i++;
			}
			if(args[i]=='\0'){
				printf("Erreur de syntaxe, pour modifier la valeur d'une option, la bonne syntaxe est les suivante : option=valeur\n\n");
				valeur=NULL;
			}
			
			if(valeur!=NULL){
				while((args[i]!='\0')&&(!isblank(args[i]))){//Lecture de la valeur
					valeur[j]=args[i];
					i++;
					j++;
				}
				valeur[j]='\0';
			}
		}
		
		if((option!=NULL)&&(valeur!=NULL)){
			if(strcasecmp(option,"ip")==0){
				if(verifIp(valeur)){
					*IP_S=valeur;
					printf("Votre nouvelle adresse ip est : %s\n",*IP_S);
					return 0;
				}
			}
			else if(strcasecmp(option,"port")==0){
				if(!atoi(valeur)){
					printf("Vous devez entrer une valeur entiere\n\n");
				}
				else{
					*PORT_S = atoi(valeur);
					printf("Votre nouveau port est : %d\n",*PORT_S);
					return 0;
				}
			}
			else if(strcasecmp(option,"path")==0){
				if ((checkdirexist(valeur))==-1) {
					printf("Chemin incorrect !\n");
				}
				else{
					*PATH_S=valeur;
					printf("Votre nouveau chemin pour les fichiers est : %s\n",*PATH_S);
					return 1;
				}
			}
			else{
				printf("L'option que vous voulez modifier n'existe pas\n");
			}
		}
	}
	return -1;
}


int decomposer_buff(const char* buf,char* cmd,char* param){
	int i=0;
	sscanf(buf, "%s", cmd);
	while((buf[i]!='\0')&&(!isblank(buf[i]))){//On va jusqu'a la fin du premier mot ou au premier espace
		i++;
	}
	while((buf[i]!='\0')&&(isblank(buf[i]))){//On va jusqu'a la fin des espaces s'il y en a
		i++;
	}
	if(buf[i]!='\0'){//On copie tout ce qui suit le premier mot dans param
		strcpy(param,&buf[i]);
	}
	else{
		return 0;
	}
	return 1;
}

